home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Linux Cubed Series 8: LINUX Games
/
Linux Cubed Series 8 - LINUX Games.iso
/
games
/
x11
/
rpg
/
crossfir.92
/
crossfir
/
crossfire-0.92.5
/
server
/
commands.c
< prev
next >
Wrap
C/C++ Source or Header
|
1996-07-24
|
21KB
|
822 lines
/*
* Command parser
*/
#include <global.h>
#include <commands.h>
#include <sproto.h>
#include <ctype.h>
#include <X11/keysym.h>
/* Added times to all the commands. However, this was quickly done,
* and probably needs more refinements. All socket and DM commands
* take 0 time.
*/
/*
* Normal game commands
*/
CommArray_s Commands[] = {
{"save", command_save, 0.0},
#ifdef SAVE_WINDOW_POSITIONS
{"savewinpos", command_savewinpos, 0.0},
#endif /* SAVE_WINDOW_POSITIONS */
#ifdef SOUND_EFFECTS
{"sound", command_sound, 0.0},
#endif
#ifdef SIMPLE_PARTY_SYSTEM
{"party", command_party, 0.0},
{"gsay", command_gsay, 1.0},
#endif
#ifdef DEBUG
{"sstable", command_sstable, 0.0},
#endif
#ifdef DEBUG_MALLOC_LEVEL
{"verify", command_malloc_verify,0.0},
#endif
{"add", command_add, 0.0},
{"apply", command_apply, 1.0}, /* should be variable */
{"archs", command_archs, 0.0},
{"bell", command_bell, 0.0},
{"berzerk", command_berzerk, 0.0},
{"bind", command_bind, 0.0},
{"brace", command_brace, 0.0},
{"cast", command_cast, 0.0}, /* Is this right? */
{"clearinfo", command_clearinfo,0.0},
{"disarm", command_disarm, 1.0},
{"dm", command_dm, 0.0},
{"drop", command_drop, 1.0},
{"dropall", command_dropall, 1.0},
{"examine", command_examine, 0.5},
{"get", command_take, 1.0},
{"help", command_help, 0.0},
{"hiscore", command_hiscore, 0.0},
{"inv-lock", command_lock, 0.0},
{"inv-unlock", command_unlock,0.0},
{"inventory", command_inventory,0.0},
{"invoke", command_invoke, 1.0},
{"keyboard", command_keyboard_flush,0.0},
{"last", command_last, 0.0},
{"listen", command_listen, 0.0},
{"malloc", command_malloc, 0.0},
{"maps", command_maps, 0.0},
{"mapinfo", command_mapinfo, 0.0},
{"motd", command_motd, 0.0},
{"output-sync", command_output_sync, 0.0},
{"output-count", command_output_count,0.0},
{"peaceful", command_peaceful,0.0},
{"pickup", command_pickup, 1.0},
{"prepare", command_prepare, 1.0},
{"quit", command_quit, 0.0},
{"refresh", command_refresh, 0.0},
{"rotateinventory", command_rotateinventory, 0.0},
{"rotateshoottype", command_rotateshoottype, 0.0},
{"rotatespells", command_rotatespells, 0.0},
{"say", command_say, 0.0},
{"scroll", command_scroll, 0.0},
{"shout", command_shout, 0.0},
{"show", command_show, 0.0},
{"showinvicon", command_show_inv_icon, 0.0},
#ifdef ALLOW_SKILLS
{"skills", command_skills, 0.0}, /* shows player list of skills */
{"use_skill", command_uskill, 0.0},
{"ready_skill", command_rskill, 0.0},
#endif
{"search",command_search, 1.0},
#ifdef SEARCH_ITEMS
{"search-items", command_search_items, 0.0},
#endif
{"strength", command_strength, 0.0},
{"strings", command_strings, 0.0},
{"sync", command_sync, 0.0},
{"take", command_take, 1.0},
{"tell", command_tell, 0.0},
{"throw", command_throw, 0.0},
{"time", command_time, 0.0},
#ifdef SET_TITLE
{"title", command_title, 0.0},
#endif
{"unbind", command_unbind, 0.0},
{"version", command_version, 0.0},
{"wimpy", command_wimpy, 0.0},
{"who", command_who, 0.0},
{"stay", command_stay, 0.0},
{"north", command_north, 1.0},
{"east", command_east, 1.0},
{"south", command_south, 1.0},
{"west", command_west, 1.0},
{"northeast", command_northeast, 1.0},
{"southeast", command_southeast, 1.0},
{"southwest", command_southwest, 1.0},
{"northwest", command_northwest, 1.0},
};
const int CommandsSize =sizeof(Commands) / sizeof(CommArray_s);
CommArray_s NewServerCommands [] = {
{"run", command_run, 1.0},
{"run_stop", command_run_stop, 0.0},
{"fire", command_fire, 1.0},
{"fire_stop", command_fire_stop, 0.0}
};
const int NewServerCommandSize = sizeof(NewServerCommands)/ sizeof(CommArray_s);
/*
* And alternative socket commands
*/
CommArray_s SocketCommands [] = {
{"add", command_add,0.0},
{"archs", command_archs,0.0},
{"bell", command_bell,0.0},
{"dm", command_dm,0.0},
{"help", command_help,0.0},
{"hiscore", command_hiscore,0.0},
{"listen", command_listen,0.0},
{"malloc", command_malloc,0.0},
{"maps", command_maps,0.0},
{"name", command_name,0.0},
{"protocol", command_protocol,0.0},
{"quit", command_quit,0.0},
{"set", command_set,0.0},
{"shout", command_shout,0.0},
{"strings", command_strings,0.0},
{"sync", command_sync,0.0},
{"tell", command_tell,0.0},
{"time", command_time,0.0},
{"unset", command_unset,0.0},
{"version", command_version,0.0},
{"who", command_who,0.0},
};
const int SocketCommandsSize =sizeof(SocketCommands) / sizeof(CommArray_s);
/*
* Wizard commands (for both)
*/
CommArray_s WizCommands [] = {
{"abil", command_abil,0.0},
{"addexp", command_addexp,0.0},
{"create", command_create,0.0},
{"debug", command_debug,0.0},
{"dump", command_dump,0.0},
{"dumpbelow", command_dumpbelow,0.0},
{"dumpfriendlyobjects", command_dumpfriendlyobjects,0.0},
{"dumplights", command_dumplights,0.0},
{"dumpallarchetypes", command_dumpallarchetypes,0.0},
{"dumpallmaps", command_dumpallmaps,0.0},
{"dumpallobjects", command_dumpallobjects,0.0},
{"dumpmap", command_dumpmap,0.0},
{"free", command_free,0.0},
{"goto", command_goto,0.0},
{"invisible", command_invisible,0.0},
{"nodm", command_nowiz,0.0},
{"nowiz", command_nowiz,0.0},
{"patch", command_patch,0.0},
{"printlos", command_printlos,0.0},
{"remove", command_remove,0.0},
{"reset", command_reset,0.0},
{"speed", command_speed,0.0},
{"spellreset", command_spell_reset,0.0},
{"ssdumptable", command_ssdumptable,0.0},
{"stats", command_stats,0.0},
{"summon", command_summon,0.0},
{"wizpass", command_wizpass,0.0},
};
const int WizCommandsSize =sizeof(WizCommands) / sizeof(CommArray_s);
static int compare_A(const void *a, const void *b)
{
return strcmp(((CommArray_s *)a)->name, ((CommArray_s *)b)->name);
}
void init_commands()
{
qsort((char *)Commands, CommandsSize, sizeof(CommArray_s), compare_A);
qsort((char *)WizCommands, WizCommandsSize, sizeof(CommArray_s), compare_A);
qsort((char *)SocketCommands, SocketCommandsSize, sizeof(CommArray_s), compare_A);
qsort((char *)NewServerCommands, NewServerCommandSize, sizeof(CommArray_s), compare_A);
}
#ifndef tolower
#define tolower(C) (((C) >= 'A' && (C) <= 'Z')? (C) - 'A' + 'a': (C))
#endif
static CommFunc find_command(char *cmd)
{
CommArray_s *asp, dummy;
char *cp;
for (cp=cmd; *cp; cp++)
*cp =tolower(*cp);
dummy.name =cmd;
asp =(CommArray_s *)bsearch((void *)&dummy,
(void *)Commands, CommandsSize,
sizeof(CommArray_s), compare_A);
if (asp)
return asp->func;
return NULL;
}
static CommFunc find_wizcommand(char *cmd)
{
CommArray_s *asp, dummy;
char *cp;
for (cp=cmd; *cp; cp++)
*cp =tolower(*cp);
dummy.name =cmd;
asp =(CommArray_s *)bsearch((void *)&dummy,
(void *)WizCommands, WizCommandsSize,
sizeof(CommArray_s), compare_A);
if (asp)
return asp->func;
return NULL;
}
static CommFunc find_socketcommand(char *cmd)
{
CommArray_s *asp, dummy;
char *cp;
for (cp=cmd; *cp; cp++)
*cp =tolower(*cp);
dummy.name =cmd;
asp =(CommArray_s *)bsearch((void *)&dummy,
(void *)SocketCommands, SocketCommandsSize,
sizeof(CommArray_s), compare_A);
if (asp)
return asp->func;
return NULL;
}
long xfire_kc2ks(player *p,KeyCode kc,long foozit)
{
if (p->eric_server == 0) {
return XKeycodeToKeysym(p->gdisp,kc,foozit);
} else {
return NoSymbol; /* esrv stuff doesn't deal with foozit -- I don't care*/
}
}
long xfire_ks2kc(player *p,KeySym ks)
{
if (p->eric_server>0) {
return esrv_ks2kc(p->eric_server,ks);
} else {
return XKeysymToKeycode(p->gdisp,ks);
}
}
void insert_key_complex(player *p, KeySym ks, KeyCode keycode, int flags, char* line)
{
int ix, len;
char *cp;
Key_s *newkey =(Key_s *)malloc(sizeof(Key_s));
#ifdef INPUT_DEBUG
if (line)
fprintf(stderr, "%i: %s (%i) 0x%x '%s'\n",
(int)p, ((cp=XKeysymToString(ks))? cp: "(null)"), (int)keycode, flags, line);
else
fprintf(stderr, "%i: %s (%i) 0x%x (null)\n",
(int)p, ((cp=XKeysymToString(ks))? cp: "(null)"), (int)keycode, flags);
#endif
if (!(newkey))
fatal(OUT_OF_MEMORY);
if (ks != NoSymbol &&
ks != xfire_kc2ks(p, keycode, 0) &&
ks != xfire_kc2ks(p, keycode, ShiftMask))
keycode =xfire_ks2kc(p, ks);
ix = (int)(keycode) % COMMAND_HASH_SIZE;
newkey->keysym =ks;
newkey->keycode =keycode;
newkey->flags =flags;
newkey->next =p->keys[ix];
newkey->params =NULL;
if (flags & KEYF_EDIT) {
newkey->func =NULL;
if (!line) {
free(newkey);
return;
}
cp =line;
} else { /* KEYF_EDIT */
if (!line) {
newkey->func =NULL;
p->keys[ix] =newkey;
return;
}
if ((cp=strchr(line, ' '))) {
*(cp++) ='\0';
if (!(newkey->func=find_command(line))) {
cp[-1] =' ';
cp =line;
}
} else { /* ' ' */
if ((newkey->func=find_command(line))) {
p->keys[ix] =newkey;
return;
}
cp =line;
} /* ' ' */
} /* KEYF_EDIT */
len =strlen(cp);
if (len && cp[len-1] == '\n')
cp[--len] ='\0';
newkey->params =(char *)malloc(len+1);
if (!newkey->params)
fatal(OUT_OF_MEMORY);
memcpy(newkey->params, cp, len+1);
p->keys[ix] =newkey;
}
void insert_key(player *p, int baseflags, char *text)
{
char *tmp;
int nro, flags, len;
if (!(tmp=strchr(text, ' '))) {
LOG(llevError, "Corrupted keysym in %s\n", text);
return;
}
*(tmp++) ='\0';
if (!(nro=strtol(tmp, NULL, 10))) {
nro= xfire_ks2kc(p, XStringToKeysym(text));
if (nro==0 && p->eric_server<1) {
LOG(llevError, "Corrupted keycode in %s\n", tmp);
return;
}
}
if (!(tmp=strchr(tmp, ' '))) {
LOG(llevError, "Corrupted flags in %s\n", text);
return;
}
flags =baseflags;
tmp++;
while (*tmp != ' ' && *tmp != '\n' && *tmp != '\0') {
switch (*tmp) {
case 'A':
flags |= KEYF_NORMAL | KEYF_FIRE | KEYF_RUN;
break;
case 'N':
flags |= KEYF_NORMAL;
break;
case 'F':
flags |= KEYF_FIRE;
break;
case 'R':
flags |= KEYF_RUN;
break;
case 'E':
flags |= KEYF_EDIT;
break;
default:
LOG(llevError, "Corrupted flags in %s\n", text);
return;
}
tmp++;
}
len =strlen(tmp);
if (len && tmp[--len] == '\n')
tmp[len] ='\0';
if (*tmp != ' ')
insert_key_complex(p, XStringToKeysym(text), (KeyCode)nro, flags, NULL);
else
insert_key_complex(p, XStringToKeysym(text), (KeyCode)nro, flags, tmp+1);
}
void load_default_keys(player *p)
{
FILE *fp;
char filename[MAX_BUF], line[MAX_BUF];
int i;
p->commandkeysym =XK_apostrophe;
p->commandkey =xfire_ks2kc(p, XK_apostrophe);
if (!p->commandkey) {
p->commandkeysym =XK_acute;
p->commandkey =xfire_ks2kc(p, XK_acute);
}
p->firekeysym[0] =XK_Shift_L;
p->firekey[0] =xfire_ks2kc(p, XK_Shift_L);
p->firekeysym[1] =XK_Shift_R;
p->firekey[1] =xfire_ks2kc(p, XK_Shift_R);
p->runkeysym[0] =XK_Control_L;
p->runkey[0] =xfire_ks2kc(p, XK_Control_L);
p->runkeysym[1] =XK_Control_R;
p->runkey[1] =xfire_ks2kc(p, XK_Control_R);
for(i=0;i<COMMAND_HASH_SIZE;i++)
while (p->keys[i]) {
Key_s *kp =p->keys[i];
if (kp->params)
free(kp->params);
p->keys[i] =kp->next;
free(kp);
}
sprintf(filename, "%s/def_keys", LibDir);
if ((fp=fopen(filename, "r")) == NULL) {
LOG(llevError, "Can't open %s\n", filename);
perror("Can't read default keys");
return;
}
while (fgets(line, MAX_BUF, fp))
if (line[0] != '#' && line[0] != '\n') {
line[MAX_BUF-1] ='\0';
insert_key(p, KEYF_DEFAULT, line);
}
fclose(fp);
}
char *find_func_name(CommFunc func)
{
int i;
for (i=0; i<CommandsSize; i++)
if (Commands[i].func == func)
return Commands[i].name;
return "(null)";
}
void dump_keys(player *p, FILE *fp)
{
int i, bi;
Key_s *key, *prev, *prev2;
char buff[4];
for (i=0; i<COMMAND_HASH_SIZE; i++) {
/* find bottom entry */
for (prev=NULL,key=p->keys[i];
key && !(key->flags & KEYF_DEFAULT);
key =key->next)
prev =key;
/* from buttom -> up */
while (prev) {
if (prev->flags & KEYF_WIZ)
continue;
if(prev->keysym == NoSymbol)
fprintf(fp, "key (null) %i ", prev->keycode);
else
fprintf(fp, "key %s %i ", XKeysymToString(prev->keysym),prev->keycode);
buff[0] ='\0'; buff[1] ='\0'; buff[2] ='\0'; buff[3] ='\0';
bi =0;
if ((prev->flags & (KEYF_NORMAL|KEYF_FIRE|KEYF_RUN)) ==
(KEYF_NORMAL|KEYF_FIRE|KEYF_RUN))
buff[bi++] ='A';
else {
if (prev->flags & KEYF_NORMAL)
buff[bi++] ='N';
if (prev->flags & KEYF_FIRE)
buff[bi++] ='F';
if (prev->flags & KEYF_RUN)
buff[bi++] ='R';
}
if (prev->flags & KEYF_EDIT)
buff[bi++] ='E';
if (prev->func)
if (prev->params)
fprintf(fp, "%s %s %s\n", buff, find_func_name(prev->func), prev->params);
else
fprintf(fp, "%s %s\n", buff, find_func_name(prev->func));
else
if (prev->params)
fprintf(fp, "%s %s\n", buff, prev->params);
else
fprintf(fp, "%s\n", buff);
/* step one up */
for (prev2=NULL,key=p->keys[i]; key != prev; key =key->next)
prev2 =key;
prev =prev2;
} /* while prev */
} /* for i */
}
void configure_keys(object *op, KeyCode k, KeySym keysym)
{
int flags;
char *cp;
if (op->contr->write_buf[0] == 'B' ||
op->contr->write_buf[0] == 'U') {
if(k == op->contr->firekey[0] || k == op->contr->firekey[1]) {
op->contr->fire_on =1;
return;
}
if(k == op->contr->runkey[0] || k == op->contr->runkey[1]) {
op->contr->run_on =1;
return;
}
}
op->contr->state = ST_PLAYING;
switch (op->contr->write_buf[0]) {
case 'C':
op->contr->commandkey =k;
op->contr->commandkeysym =keysym;
goto done;
case 'F':
op->contr->firekey[0] =k;
op->contr->firekeysym[0] =keysym;
goto done;
case 'f':
op->contr->firekey[1] =k;
op->contr->firekeysym[1] =keysym;
goto done;
case 'R':
op->contr->runkey[0] =k;
op->contr->runkeysym[0] =keysym;
goto done;
case 'r':
op->contr->runkey[1] =k;
op->contr->runkeysym[1] =keysym;
goto done;
case 'B':
flags =strtol(op->contr->write_buf+1, &cp, 10);
if (!cp || !flags) {
LOG(llevError, "Corrupted line to bind!\n");
return;
}
if (*cp == ' ')
cp++;
if (flags & 0x1000)
insert_key_complex(op->contr, NoSymbol, k, (flags&0xfff)|KEYF_USER, cp);
else
insert_key_complex(op->contr, keysym, k, flags|KEYF_USER, cp);
goto done;
}
LOG(llevError, "Got to end of configure??\n");
return;
/*
* Post config
*/
done:
new_draw_info_format(NDI_UNIQUE, 0, op,
"Binded to key '%s' (%i)", XKeysymToString(keysym), (int)k);
op->contr->fire_on=0;
op->contr->run_on=0;
return;
}
/*
* parse_string may be called from a player in the game or from a socket
* (op is NULL if it's a socket).
* It returnes 1 if it recognized the command, otherwise 0.
* Actually return value is used as can-repeat -flag
*/
int parse_string(object *op, char *str)
{
CommFunc f;
char *cp;
#ifdef INPUT_DEBUG
LOG(llevDebug, "Command: '%s'\n", str);
#endif
/*
* No arguments?
*/
if (!(cp=strchr(str, ' '))) {
if (!op) {
if(active_socket == (sockets *) NULL) {
LOG(llevError,"parse_string without active socket: %s\n",str);
return 0;
}
if ((f=find_socketcommand(str)))
return f(op, NULL);
if (active_socket->wiz && (f=find_wizcommand(str)))
return f(op, NULL);
new_draw_info_format(NDI_UNIQUE, 0, op, "Unknown command: %s", str);
return 0;
}
op->contr->writing =0;
if(!op->contr->no_echo) {
new_draw_info_format(NDI_UNIQUE, 0, op,
">%s", str);
}
if ((f=find_command(str)))
return f(op, NULL);
if (QUERY_FLAG(op,FLAG_WIZ) && (f=find_wizcommand(str)))
return f(op, NULL);
if(op) {
op->contr->no_echo = 0;
new_draw_info(NDI_UNIQUE, 0,op, "Unknown command. Try help.");
}
return 0;
} /* ' ' */
/*
* Command with some arguments
*/
*(cp++) ='\0';
if (!op) {
if(active_socket == (sockets *) NULL) {
LOG(llevError,"parse_string without active socket: %s %s\n",str, cp);
return 0;
}
if ((f=find_socketcommand(str)))
return f(op, cp);
if (active_socket->wiz && (f=find_wizcommand(str)))
return f(op, cp);
return 0;
}
op->contr->writing =0;
if(!op->contr->no_echo) {
new_draw_info_format(NDI_UNIQUE, 0, op,
">%s %s", str, cp);
}
if ((f=find_command(str)))
return f(op, cp);
if (QUERY_FLAG(op, FLAG_WIZ) && (f=find_wizcommand(str)))
return f(op, cp);
if(op) {
op->contr->no_echo = 0;
new_draw_info(NDI_UNIQUE, 0,op, "Unknown command. Try help.");
}
return 0;
}
int parse_writing(object *op, char k)
{
player *pl=op->contr;
if (k != 13) {
write_ch(op, k);
return 1;
}
if(pl->write_buf[0] != '>')
LOG(llevError, "Corrupted commandline (%s)\n", pl->write_buf);
pl->write_buf[pl->writing] ='\0';
return parse_string(op, pl->write_buf+1);
}
int parse_key(object *op, char k, KeyCode kc, KeySym keysym)
{
int i, ix;
Key_s *key;
player *pl=op->contr;
static char p_buff[MAX_BUF];
char *charkey;
#ifdef INPUT_DEBUG
if (k >= ' ')
fprintf(stderr, "Key '%c' Keycode %d Keysym '%s'\n",
k, (int)kc, XKeysymToString(keysym));
else
fprintf(stderr, "Keycode %d Keysym '%s'\n",
(int)kc, XKeysymToString(keysym));
#endif
if(pl->viewmap) {
pl->viewmap=0;
refresh(op);
}
if (kc == pl->commandkey && keysym == pl->commandkeysym &&
!pl->writing) {
write_ch(op,'>');
pl->count=0;
return 1;
}
if ((kc == pl->firekey[0] && keysym == pl->firekeysym[0]) ||
(kc == pl->firekey[1] && keysym == pl->firekeysym[1]))
return pl->fire_on=1;
if ((kc == pl->runkey[0] && keysym == pl->runkeysym[0]) ||
(kc == pl->runkey[1] && keysym == pl->runkeysym[1]))
return pl->run_on=1;
if(pl->writing) {
if (keysym != NoSymbol &&
!(IsKeypadKey(keysym) || IsCursorKey(keysym) || IsPFKey(keysym) ||
IsFunctionKey(keysym) || IsMiscFunctionKey(keysym) ||
IsModifierKey(keysym)))
return parse_writing(op, k);
}
pl->prev_keycode =kc,
pl->prev_keysym =keysym,
pl->prev_cmd =k;
pl->prev_fire_on =pl->fire_on;
ix =(int)(kc) % COMMAND_HASH_SIZE;
for (key=pl->keys[ix]; key ; key =key->next) {
if ((key->keycode != kc) ||
(key->keysym != NoSymbol && key->keysym != keysym) ||
(key->flags & KEYF_WIZ && !QUERY_FLAG(op, FLAG_WIZ)) ||
(pl->fire_on && !(key->flags & KEYF_FIRE)) ||
(pl->run_on && !(key->flags & KEYF_RUN)) ||
(!pl->fire_on && !pl->run_on &&
!(key->flags & KEYF_NORMAL)))
continue;
if (key->func) {
if (key->params) {
strcpy(p_buff, key->params);
return (key->func)(op, p_buff);
}
return (key->func)(op, NULL);
}
if (key->params) {
if (!(key->flags & KEYF_EDIT))
return parse_string(op, key->params);
if (pl->writing)
return 1;
write_ch(op, '>');
for (i=0; key->params[i]; i++)
write_ch(op, key->params[i]);
return 1;
}
return 1;
}
if(k >= '0' && k <= '9') {
pl->count =((k-'0')+(int)pl->count*10) % 100000;
new_draw_info_format(NDI_UNIQUE, 0, op,
"Count: %d.", pl->count);
return 1;
}
charkey=XKeysymToString(keysym);
new_draw_info_format(NDI_UNIQUE, 0, op,
"Key unused (%s%s%s)",
(pl->fire_on? "Fire&": ""),
(pl->run_on ? "Run&" : ""),
(charkey ? charkey:"(null)"));
pl->count_left=0;
pl->count=0;
return 1;
}
void handle_keyrelease(object *op,KeyCode kc,KeySym ks)
{
player *pl = op->contr;
pl->key_down=0;
/* If in ST_MENU_MORE mode, we need to catch the release of shift
* key, from the user typing shift-a- A)pply (the menu sign). Otherwise,
* the player is frozen in place until shift is pressed again.
* Mark Wedel (master@cats.ucsc.edu)
*/
if ((kc == pl->firekey[0] && ks == pl->firekeysym[0]) ||
(kc == pl->firekey[1] && ks == pl->firekeysym[1])) {
pl->fire_on=0;
return;
}
if ((kc == pl->runkey[0] && ks == pl->runkeysym[0]) ||
(kc == pl->runkey[1] && ks == pl->runkeysym[1])) {
pl->run_on=0;
return;
}
}
void parse_key_release(object *op)
{
KeyCode kc=op->contr->gevent.xkey.keycode;
KeySym ks=op->contr->gkey;
handle_keyrelease(op,kc,ks);
}